You create an offscreen graphics world with the NewGWorld function. It creates a new offscreen graphics port, a new offscreen pixel map, and (on computers that support Color QuickDraw) either a new offscreen GDevice record or a link to an existing one. It returns a data structure of type GWorldPtr by which your application refers to your new offscreen graphics world. Listing 6-1 illustrates how to create an offscreen graphics world.
Listing 1Using a single offscreen graphics world and the CopyBits procedure
PROCEDURE MyPaintRectsThruGWorld (wp: WindowPtr);
VAR
origPort: GrafPtr;
origDev: GDHandle;
myErr: QDErr;
myOffGWorld: GWorldPtr;
offPixMapHandle: PixMapHandle;
good: Boolean;
sourceRect, destRect: Rect;
BEGIN
GetGWorld(origPort, origDev); {save window's graphics port}
myErr := NewGWorld(myOffGWorld, 0, {create offscreen graphics world, }
wp^.portRect, { using window's port rectangle}
NIL, NIL, []);
IF (myOffGWorld = NIL) OR (myErr <> noErr) THEN
; {handle error here}
SetGWorld(myOffGWorld, NIL); {make offscreen world the current port}
offPixMapHandle := GetGWorldPixMap(myOffGWorld); {get handle to }
good := LockPixels(offPixMapHandle); { offscreen pixel image and lock it}
IF NOT good THEN
; {handle error here}
EraseRect(myOffGWorld^.portRect); {initialize its pixel image}
MyPaintAndFillColorRects; {paint a blue rectangle, fill a green rectangle}
SetGWorld(origPort, origDev); {make window the current port}
{next, for CopyBits, create source and destination rectangles that }
{ exclude scroll bar areas}
sourceRect := myOffGWorld^.portRect; {use offscreen portRect for source}
sourceRect.bottom := myOffGWorld^.portRect.bottom - 15;
sourceRect.right := myOffGWorld^.portRect.right - 15;
destRect := wp^.portRect; {use window portRect for destination}
destRect.bottom := wp^.portRect.bottom - 15;
destRect.right := wp^.portRect.right - 15;
{next, use CopyBits to transfer the offscreen image to the window}
CopyBits(GrafPtr(myOffGWorld)^.portBits, {coerce graphics world's }
{ PixMap to a BitMap}
GrafPtr(wp)^.portBits, {coerce window's PixMap to a BitMap}
sourceRect, destRect, srcCopy, NIL);
IF QDError <> noErr THEN
; {likely error is that there is insufficient memory}
UnlockPixels(offPixMapHandle); {unlock the pixel image}
DisposeGWorld(myOffGWorld); {dispose of offscreen world}
END;
When you use NewGWorld , you can specify a pixel depth, a boundary rectangle (which also becomes the port rectangle), a color table, a GDevice record, and option flags for memory allocation for the offscreen graphics world. Typically, however, you pass 0 as the pixel depth, a window's port rectangle as the offscreen world's boundary rectangle, NIL for both the color table and GDevice record, and an empty set ([ ]) in your Pascal code or 0 in your C code for the option flags. This provides your application with the default behavior of NewGWorld , and it supports computers running only basic QuickDraw. This also allows QuickDraw to optimize the CopyBits , CopyMask , and CopyDeepMask procedures when your application copies the image you create in an offscreen graphics world into the window's port rectangle.
When creating an offscreen graphics world, if you specify 0 as the pixel depth, the port rectangle for a window as the boundary rectangle, and no option flags, the NewGWorld function
The application-defined routine MyPaintRectsThruGWorld in Listing 6-1 , for example, specifies the default behavior for NewGWorld . The MyPaintRectsThruGWorld routine dereferences the window pointer passed in the wp parameter to obtain a window's port rectangle, which MyPaintRectsThruGWorld passes to NewGWorld as the boundary and port rectangle for the offscreen graphics world.